'''
Created on 17/09/2009

@author: b1u3fox
'''
import pygtk
pygtk.require("2.0")
import gtk
import gobject
import pango
import os.path

from logica.tablaverdad import TablaVerdad
from logica.proposiciones import *
from interprete.parser import Parser
from gui.resaltadorsintaxis import ResaltadorSintaxis

class VentanaTablaVerdad(gtk.Window):
    
    def crear_widgets(self, columnas):
        # Layout widgets
        self.caja_principal = gtk.VBox()
        #self.vd_tabla = gtk.ScrolledWindow()
        # List widgets
        self.renderers = {}
        self.columnas = {}
        self.columna_order = []
        types = [columna[1] for columna in columnas]
        self.mdl_tabla = gtk.ListStore(*types)
        self.tvw_tabla = gtk.TreeView(self.mdl_tabla)
        self.tvw_tabla.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
        id = 0
        for columna in columnas:
            renderer = gtk.CellRendererText()
            self.renderers[columna[0]] = renderer
            col = gtk.TreeViewColumn(columna[2], renderer, text=id)
            # TODO: Alinear al centro
            renderer.set_property('xalign', 0.5)
            col.set_alignment(0.5)
            col.set_sort_column_id(id)
            self.columnas[columna[0]] = col
            self.tvw_tabla.append_column(col)
            id += 1
            self.columna_order.append(columna[0])
    
    def set_layout(self):
        # Base layout
        self.add(self.caja_principal)
        self.caja_principal.pack_start(self.tvw_tabla)
#        self.caja_principal.pack_start(self.vd_tabla)
#        self.vd_tabla.add(self.tvw_tabla)
    
    def set_visibility(self):
        self.tvw_tabla.show()
#        self.vd_tabla.show()
        self.caja_principal.show()
    
    def __init__(self, columnas):
        gtk.Window.__init__(self)
        #self.set_default_size(200, 300)
        self.set_title('Tabla de Verdad')
        self.crear_widgets(columnas)
        self.set_layout()
        self.set_visibility()

class CuadernoEjercicios(gtk.Notebook):
    def remover_hoja(self, widget, scw):
        numero_hoja = self.page_num(scw)
        if self.revisar_modificacion(numero_hoja):
            self.remove_page(numero_hoja)
        
    def revisar_modificacion(self, numero_hoja):
        scw = self.get_nth_page(numero_hoja)
        if not scw.label.get_label().startswith('*'):
            return True
        else:
            #d
            if self.desea_guardar(scw):
                if scw.nombre_archivo:
                    self.guardar(scw)
                else:
                    self.guardar_como(scw)
            
        
    def marcar_modificado(self, widget, scw):
        if not scw.label.get_label().startswith('*'):
            scw.label.set_label('*' + scw.label.get_label())
    
    def agregar_hoja_desde_archivo(self, nombre_archivo=None):
        # Creamos la etiqueta de la pestana incluyendo el boton de cierre.
        hbox = gtk.HBox()
        lbl = gtk.Label(os.path.basename(nombre_archivo))
        lbl.set_tooltip_text(nombre_archivo)
        img = gtk.Image()
        img.set_from_file('icons/cerrarpestana.png')
        img.set_padding(0, 0)
        btn_cerrar = gtk.Button()
        btn_cerrar.set_image(img)
        btn_cerrar.set_relief(gtk.RELIEF_NONE)
        hbox.pack_start(lbl)
        hbox.pack_start(btn_cerrar)
        hbox.show_all()
        # Creamos la ventana de desplazable con el resaltador de sintaxis.
        scw = gtk.ScrolledWindow()
        scw.resaltador_sintaxis = ResaltadorSintaxis()
        scw.label = lbl
        scw.nombre_archivo = nombre_archivo
        scw.add(scw.resaltador_sintaxis)
        numero_hoja = self.append_page(scw, hbox)
        self.set_tab_reorderable(scw, True)
        btn_cerrar.connect('clicked', self.remover_hoja, scw)
        archivo = open(nombre_archivo)
        contenido = archivo.read()
        archivo.close()
        if contenido:
            text_buffer = scw.resaltador_sintaxis.get_buffer()
            text_buffer.set_text(contenido)
            scw.resaltador_sintaxis.resaltar_sintaxis()
            text_buffer.set_modified(False)
            text_buffer.connect('changed', self.marcar_modificado, scw)
        # Mostramos todo y ponemos activa la hoja recien agregada
        self.show_all()
        self.set_current_page(numero_hoja)
    
    def agregar_hoja(self):
        # Creamos la etiqueta de la pestana incluyendo el boton de cierre.
        hbox = gtk.HBox()
        lbl = gtk.Label('Nuevo %d' % self.indice_nuevo)
        self.indice_nuevo += 1
        img = gtk.Image()
        img.set_from_file('icons/cerrarpestana.png')
        img.set_padding(0, 0)
        btn_cerrar = gtk.Button()
        btn_cerrar.set_image(img)
        btn_cerrar.set_relief(gtk.RELIEF_NONE)
        hbox.pack_start(lbl)
        hbox.pack_start(btn_cerrar)
        hbox.show_all()
        # Creamos la ventana de desplazable con el resaltador de sintaxis.
        scw = gtk.ScrolledWindow()
        scw.resaltador_sintaxis = ResaltadorSintaxis()
        text_buffer = scw.resaltador_sintaxis.get_buffer()
        text_buffer.set_modified(False)
        text_buffer.connect('changed', self.marcar_modificado, scw)
        scw.label = lbl
        scw.nombre_archivo = None
        scw.add(scw.resaltador_sintaxis)
        numero_hoja = self.append_page(scw, hbox)
        self.set_tab_reorderable(scw, True)
        btn_cerrar.connect('clicked', self.remover_hoja, scw)
        # Mostramos todo y ponemos activa la hoja recien agregada
        self.show_all()
        self.set_current_page(numero_hoja)
        
    def cargar_archivos(self, nombres_archivos):
        for nombre_archivo in nombres_archivos:
            self.agregar_hoja_desde_archivo(nombre_archivo)
    
    def __init__(self, nombres_archivos=[]):
        gtk.Notebook.__init__(self)
        self.set_scrollable(True)
        self.indice_nuevo = 1
        if nombres_archivos:
            self.cargar_archivos(nombres_archivos)
        else:
            self.agregar_hoja()

class VentanaPpal(gtk.Window):
    
    def crear_stocks(self):
        stocks = []
        key, mod = gtk.accelerator_parse('F9')
        stock_tabla_verdad = ('STOCK_TABLA_VERDAD', '_Tabla de verdad...',
                              key, mod, 'VentanaPpal')
        stocks.append(stock_tabla_verdad)
        key, mod = gtk.accelerator_parse('F10')
        stock_sugerencias = ('STOCK_SUGERENCIAS', '_Sugerencias',
                              key, mod, 'VentanaPpal')
        stocks.append(stock_sugerencias)
        key, mod = gtk.accelerator_parse('F11')
        stock_verificar = ('STOCK_VERIFICAR', '_Verificar',
                              key, mod, 'VentanaPpal')
        stocks.append(stock_verificar)
        key, mod = gtk.accelerator_parse('F12')
        stock_resolver = ('STOCK_RESOLVER', '_Resolver',
                              key, mod, 'VentanaPpal')
        stocks.append(stock_resolver)
        key, mod = gtk.accelerator_parse('F8')
        stock_tutor = ('STOCK_TUTOR', '_Tutor',
                              key, mod, 'VentanaPpal')
        stocks.append(stock_tutor)
        gtk.stock_add(stocks)
    
    def crear_menu_archivo(self):
        self.menu_archivo = gtk.Menu()
        self.mi_nuevo = gtk.ImageMenuItem(gtk.STOCK_NEW, self.grp_acel)
        self.mi_abrir = gtk.ImageMenuItem(gtk.STOCK_OPEN, self.grp_acel)
        self.mi_guardar = gtk.ImageMenuItem(gtk.STOCK_SAVE, self.grp_acel)
        self.mi_guardar_como = gtk.ImageMenuItem(gtk.STOCK_SAVE_AS)
        self.mi_cerrar = gtk.ImageMenuItem(gtk.STOCK_CLOSE, self.grp_acel)
        self.mi_imprimir = gtk.ImageMenuItem(gtk.STOCK_PRINT, self.grp_acel)
        self.mi_salir = gtk.ImageMenuItem(gtk.STOCK_QUIT, self.grp_acel)
        key, mod = gtk.accelerator_parse("<Control>p")
        self.mi_imprimir.add_accelerator("activate", self.grp_acel, key, mod, 
                                         gtk.ACCEL_VISIBLE)
        self.menu_archivo.append(self.mi_nuevo)
        self.menu_archivo.append(self.mi_abrir)
        self.menu_archivo.append(self.mi_guardar)
        self.menu_archivo.append(self.mi_guardar_como)
        self.menu_archivo.append(self.mi_cerrar)
        self.menu_archivo.append(gtk.SeparatorMenuItem())
        self.menu_archivo.append(self.mi_imprimir)
        self.menu_archivo.append(gtk.SeparatorMenuItem())
        self.menu_archivo.append(self.mi_salir)
    
    def crear_menu_editar(self):
        self.menu_editar = gtk.Menu()
        self.mi_deshacer = gtk.ImageMenuItem(gtk.STOCK_UNDO, self.grp_acel)
        key, mod = gtk.accelerator_parse("<Control>z")
        self.mi_deshacer.add_accelerator("activate", self.grp_acel, key, mod, 
                                         gtk.ACCEL_VISIBLE)
        self.mi_rehacer = gtk.ImageMenuItem(gtk.STOCK_REDO, self.grp_acel)
        key, mod = gtk.accelerator_parse("<Control>y")
        self.mi_rehacer.add_accelerator("activate", self.grp_acel, key, mod, 
                                         gtk.ACCEL_VISIBLE)
        self.mi_copiar = gtk.ImageMenuItem(gtk.STOCK_COPY, self.grp_acel)
        self.mi_cortar = gtk.ImageMenuItem(gtk.STOCK_CUT, self.grp_acel)
        self.mi_pegar = gtk.ImageMenuItem(gtk.STOCK_PASTE, self.grp_acel)
        self.mi_preferencias = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES, 
                                                 self.grp_acel)
        self.menu_editar.append(self.mi_deshacer)
        self.menu_editar.append(self.mi_rehacer)
        self.menu_editar.append(gtk.SeparatorMenuItem())
        self.menu_editar.append(self.mi_copiar)
        self.menu_editar.append(self.mi_cortar)
        self.menu_editar.append(self.mi_pegar)
        self.menu_editar.append(gtk.SeparatorMenuItem())
        self.menu_editar.append(self.mi_preferencias)
    
    def crear_menu_herramientas(self):
        self.menu_herramientas = gtk.Menu()
        self.mi_tabla_verdad = gtk.ImageMenuItem('STOCK_TABLA_VERDAD', 
                                                 self.grp_acel)
        img = gtk.Image()
        img.set_from_file('icons/tablaverdad16x16.png')
        self.mi_tabla_verdad.set_image(img)
        self.mi_sugerencias = gtk.ImageMenuItem('STOCK_SUGERENCIAS', 
                                                 self.grp_acel)
        img = gtk.Image()
        img.set_from_file('icons/sugerencias16x16.png')
        self.mi_sugerencias.set_image(img)
        self.mi_verificar = gtk.ImageMenuItem('STOCK_VERIFICAR', 
                                                 self.grp_acel)
        img = gtk.Image()
        img.set_from_file('icons/verificar16x16.png')
        self.mi_verificar.set_image(img)
        self.mi_resolver = gtk.ImageMenuItem('STOCK_RESOLVER', 
                                                 self.grp_acel)
        img = gtk.Image()
        img.set_from_file('icons/resolver16x16.png')
        self.mi_resolver.set_image(img)
        self.menu_herramientas.append(self.mi_tabla_verdad)
        self.menu_herramientas.append(self.mi_sugerencias)
        self.menu_herramientas.append(self.mi_verificar)
        self.menu_herramientas.append(self.mi_resolver)
    
    def crear_menu_ayuda(self):
        self.menu_ayuda = gtk.Menu()
        self.mi_manual = gtk.ImageMenuItem(gtk.STOCK_HELP, self.grp_acel)
        self.mi_tutor = gtk.ImageMenuItem('STOCK_TUTOR', 
                                                 self.grp_acel)
        img = gtk.Image()
        img.set_from_file('icons/tutor16x16.png')
        self.mi_tutor.set_image(img)
        self.mi_acerca_de = gtk.MenuItem('_Acerca de...')
        self.menu_ayuda.append(self.mi_manual)
        self.menu_ayuda.append(self.mi_tutor)
        self.menu_ayuda.append(gtk.SeparatorMenuItem())
        self.menu_ayuda.append(self.mi_acerca_de)
    
    def crear_barra_menu(self):
        self.grp_acel = gtk.AccelGroup()
        self.add_accel_group(self.grp_acel)
        self.barra_menu = gtk.MenuBar()
        self.mi_archivo = gtk.MenuItem('_Archivo')
        self.crear_menu_archivo()
        self.mi_archivo.set_submenu(self.menu_archivo)
        self.mi_editar = gtk.MenuItem(label='_Editar')
        self.crear_menu_editar()
        self.mi_editar.set_submenu(self.menu_editar)
        self.mi_herramientas = gtk.MenuItem(label='_Herramientas')
        self.crear_menu_herramientas()
        self.mi_herramientas.set_submenu(self.menu_herramientas)
        self.mi_ayuda = gtk.MenuItem(label='_?')
        self.crear_menu_ayuda()
        self.mi_ayuda.set_submenu(self.menu_ayuda)
        self.barra_menu.append(self.mi_archivo)
        self.barra_menu.append(self.mi_editar)
        self.barra_menu.append(self.mi_herramientas)
        self.barra_menu.append(self.mi_ayuda)
        
    def crear_barra_herramientas(self):
        self.barra_herramientas = gtk.Toolbar()
        self.tb_nuevo = gtk.ToolButton(gtk.STOCK_NEW)
        self.tb_abrir = gtk.ToolButton(gtk.STOCK_OPEN)
        self.tb_guardar = gtk.ToolButton(gtk.STOCK_SAVE)
        self.tb_imprimir = gtk.ToolButton(gtk.STOCK_PRINT)
        self.tb_deshacer = gtk.ToolButton(gtk.STOCK_UNDO)
        self.tb_rehacer = gtk.ToolButton(gtk.STOCK_REDO)
        self.tb_copiar = gtk.ToolButton(gtk.STOCK_COPY)
        self.tb_cortar = gtk.ToolButton(gtk.STOCK_CUT)
        self.tb_pegar = gtk.ToolButton(gtk.STOCK_PASTE)
        self.tb_verificar = gtk.ToolButton('STOCK_VERIFICAR')
        img = gtk.Image()
        img.set_from_file('icons/verificar22x22.png')
        self.tb_verificar.set_icon_widget(img)
        self.tb_resolver = gtk.ToolButton('STOCK_RESOLVER')
        img = gtk.Image()
        img.set_from_file('icons/resolver22x22.png')
        self.tb_resolver.set_icon_widget(img)
        self.barra_herramientas.add(self.tb_nuevo)
        self.barra_herramientas.add(self.tb_abrir)
        self.barra_herramientas.add(self.tb_guardar)
        self.barra_herramientas.add(self.tb_imprimir)
        self.barra_herramientas.add(gtk.SeparatorToolItem())
        self.barra_herramientas.add(self.tb_deshacer)
        self.barra_herramientas.add(self.tb_rehacer)
        self.barra_herramientas.add(gtk.SeparatorToolItem())
        self.barra_herramientas.add(self.tb_copiar)
        self.barra_herramientas.add(self.tb_cortar)
        self.barra_herramientas.add(self.tb_pegar)
        self.barra_herramientas.add(gtk.SeparatorToolItem())
        self.barra_herramientas.add(self.tb_verificar)
        self.barra_herramientas.add(self.tb_resolver)
        
    def crear_cuaderno(self, nombres_archivos):
        self.cuaderno = CuadernoEjercicios(nombres_archivos)
        
    def crear_barra_estado(self):
        self.barra_estado = gtk.Statusbar()
    
    def crear_widgets(self, nombres_archivos):
        # Layout widgets
        self.main_box = gtk.VBox()
        self.crear_barra_menu()
        self.crear_barra_herramientas()
        self.crear_cuaderno(nombres_archivos)
        self.crear_barra_estado()
        self.caja_horizontal = gtk.HBox()
    
    def establecer_disposicion(self):
        # Base layout
        self.add(self.main_box)
        self.main_box.pack_start(self.barra_menu, expand=False, fill=False)
        self.main_box.pack_start(self.barra_herramientas, expand=False, 
                                 fill=False)
        self.main_box.pack_start(self.caja_horizontal, expand=True, fill=True)
        self.caja_horizontal.pack_start(self.cuaderno, expand=True, fill=True)
        self.main_box.pack_start(self.barra_estado, expand=False, fill=False)
        
    def cerrar_hoja_activa(self, widget):
        numero_hoja = self.cuaderno.get_current_page()
        self.cuaderno.remove_page(numero_hoja)
        
    def crear_nueva_hoja(self, widget):
        self.cuaderno.agregar_hoja()
        
    def abrir(self, widget, respuesta):
        if respuesta == gtk.RESPONSE_ACCEPT:
            nombre_archivo = self.file_chooser_dialog.get_filename()
            self.cuaderno.agregar_hoja_desde_archivo(nombre_archivo)
        self.file_chooser_dialog.hide()
        
    def mostrar_dialogo_abrir(self, widget):
        self.file_chooser_dialog = gtk.FileChooserDialog('Abrir...', None, 
            gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL,
                                           gtk.RESPONSE_REJECT,
                                           gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
        self.file_chooser_dialog.connect('response', self.abrir)
        self.file_chooser_dialog.show()
        
    def generar_tabla_verdad(self, widget):
        numero_hoja = self.cuaderno.get_current_page()
        scw = self.cuaderno.get_nth_page(numero_hoja)
        text_buffer = scw.resaltador_sintaxis.get_buffer()
        if text_buffer.get_char_count() > 0:
            start, end = text_buffer.get_selection_bounds()
            if start and end:
                cadena = text_buffer.get_text(start, end)
                self.parser = Parser()
                proposicion = self.parser.parse_proposicion(cadena)
                if proposicion:
                    tabla_verdad = TablaVerdad(proposicion)
                    columnas = []
                    for proposicion in tabla_verdad.proposiciones:
                        columnas.append((proposicion, gobject.TYPE_STRING, 
                                        str(proposicion)))
                    ventana_tabla_verdad = VentanaTablaVerdad(columnas)
                    ventana_tabla_verdad.set_modal(True)
                    for fila in tabla_verdad.filas:
                        data = []
                        for valor in fila:
                            if valor:
                                data.append('V')
                            else:
                                data.append('F')
                        ventana_tabla_verdad.mdl_tabla.append(data)
                    ventana_tabla_verdad.show()
        
    def conectar_widgets(self):
        self.mi_nuevo.connect('activate', self.crear_nueva_hoja)
        self.mi_abrir.connect('activate', self.mostrar_dialogo_abrir)
        self.mi_cerrar.connect('activate', self.cerrar_hoja_activa)
        self.mi_tabla_verdad.connect('activate', self.generar_tabla_verdad)
        self.tb_nuevo.connect('clicked', self.crear_nueva_hoja)
        self.tb_abrir.connect('clicked', self.mostrar_dialogo_abrir)
        
    def en_destruccion(self, widget=None, params=None):
        gtk.main_quit()
        
    def __init__(self, argumentos):
        gtk.Window.__init__(self)
        self.set_default_size(780, 580)
        self.set_position(gtk.WIN_POS_CENTER)
        self.set_icon_from_file('icons/paradoja16x16.png')
        self.set_title('Paradoja')
        self.clipboard = gtk.Clipboard()
        self.crear_stocks()
        self.crear_widgets(argumentos)
        self.establecer_disposicion()
        self.conectar_widgets()
        self.indice_nuevo = 1
        self.connect("destroy", self.en_destruccion)
